package net.wendal.base.type;

import java.util.*;

/**
 * Created by y on 2017/2/7.
 */
public class PetsTest {



}

/**
 * 进行计数
 */
class PetCount {

    public static void main(String[] args) {
        countPets(new ForNameCreator(), 20);
    }

    static class PetCounter extends HashMap<String, Integer>{
        public void count(String type) {
            Integer quantity = get(type);
            if (null == quantity)
                put(type, 1);
            else
                put(type, quantity + 1);
        }
    }

    public static void countPets(PetCreator petCreator, int size) {
        PetCounter petCounter = new PetCounter();
        for (Pet pet : petCreator.createArray(size)) {
            System.out.print(pet.getClass().getSimpleName() + " ");
            if (pet.getClass() == Pet.class) {
                petCounter.count("pet");
            }
            if (pet.getClass() == Cat.class) {
                petCounter.count("cat");
            }
            if (pet.getClass() == Dog.class) {
                petCounter.count("dog");
            }
            if (pet.getClass() == Pug.class) {
                petCounter.count("pug");
            }
        }
        System.out.println();
        System.out.println(petCounter);
    }
}

/**
 * 具体实现类
 */
class ForNameCreator extends PetCreator {

    private static List<Class<? extends Pet>> types = new ArrayList<Class<? extends Pet>>();

    private static String[] typeNames = {"net.wendal.base.type.Cat",
            "net.wendal.base.type.Dog",
            "net.wendal.base.type.Pug"};

    private static void loader() {
        for (String name : typeNames) {
            try {
                types.add((Class<? extends Pet>) Class.forName(name));
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    static {
        loader();
    }

    @Override
    public List<Class<? extends Pet>> types() {
        return types;
    }
}

/**
 * 具体实现类 实用类字面常量 改写上面使用instanceof
 */
class LiteralPetCreator extends PetCreator{

    public static final List<Class<? extends Pet>> allTypes =
            Collections.unmodifiableList(Arrays.asList(Pet.class, Dog.class, Cat.class, Pug.class));

    private static final List<Class<? extends Pet>> types = allTypes.subList(allTypes.indexOf(Pet.class), allTypes.size());

    @Override
    public List<Class<? extends Pet>> types() {
        return types;
    }

    public static void main(String[] args) {
        System.out.println(types);
    }
}

/**
 * 抽象类
 */
abstract class PetCreator {
    private Random random = new Random(47);

    public abstract List<Class<? extends Pet>> types();

    public Pet randomPet() {
        int i = random.nextInt(types().size());
        try {
            return types().get(i).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    public Pet[] createArray(int size) {
        Pet[] pets =  new Pet[size];
        for (int i= 0; i < size; i++)
            pets[i] = randomPet();
        return pets;
    }

    public ArrayList<Pet> arrayList(int size) {
        ArrayList<Pet> pets = new ArrayList<Pet>(size);
        Collections.addAll(pets, createArray(size));
        return pets;
    }

}

class Individual {
    Individual() {}
    Individual(String name) {

    }
}

class Person extends Individual {
    Person(String name) {
        super(name);
    }

}

class Pet extends Individual {
    Pet() {
        super();
    }
    Pet(String name) {
        super(name);
    }
}

class Cat extends Pet {
    Cat() {
        super();
    }
    Cat(String name) {
        super(name);
    }
}

class Dog extends Pet {
    Dog() {
        super();
    }
    Dog(String name) {
        super(name);
    }
}

class Pug extends Dog {
    Pug() {
        super();
    }
    Pug(String name) {
        super(name);
    }
}
